package org.iks.common.util;

import cn.hutool.crypto.digest.MD5;
import org.apache.commons.codec.digest.MurmurHash3;

import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

/**
 * @author kzou
 * @date 2023/12/17 10:30
 * @description: 哈希计算
 */
public class HashUtil {
    private static final String chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";

    public static long hash(String data) {
        return hash32(data, StandardCharsets.UTF_8);
    }

    /**
     * hash 运算
     * @param data 原字符串数据
     * @param charset 数据编码
     * @return 10进制hash结果
     */
    public static long hash32(String data, Charset charset) {
        byte[] bytes = data.getBytes(charset);
        return MurmurHash3.hash32x86(bytes);
    }

    /**
     * 十进制数字转62进制
     * @param num 十进制数字
     * @return 62进制结果
     */
    public static String encodeBase62(long num) {
        StringBuilder sb = new StringBuilder();
        int scale = chars.length();
        int remainder;
        while (num > scale - 1) {
            // 对 scale 进行求余，然后将余数追加至 sb 中，由于是从末位开始追加的，因此最后需要反转字符串
            remainder = Long.valueOf(num % scale).intValue();
            sb.append(chars.charAt(remainder));
            // 除以进制数，获取下一个末尾数
            num = num / scale;
        }
        sb.append(chars.charAt(Long.valueOf(num).intValue()));
        return sb.reverse().toString();
    }

    /**
     * 62进制转为进制
     * @param str 62进制
     * @return 十进制数字
     */
    public static long decodeBase62(String str) {
        int scale = chars.length();
        long value = 0;
        char tempChar;
        int tempCharValue;
        for (int i = 0; i < str.length(); i++) {
            // 获取字符
            tempChar = str.charAt(i);
            // 单字符值
            tempCharValue = chars.indexOf(tempChar);
            // 单字符值在进制规则下表示的值
            value += (long) (tempCharValue * Math.pow(scale, str.length() - i - 1));
        }
        return value;
    }

    public static String md5(String data) {
        return MD5.create().digestHex16(data);
    }

}
